#include "chatcommand_simplegameusersetdata.h"
#include "websocket.h"
#include "datastring.h"
#include "parameters.h"
#include "stringbuilder.h"
#include "message.h"
#include "Debug.h"
#include <inttypes.h>
#include "simplechatgame.h"

// simplegameusersetdata(messageid,gameid,userdata)
// Sets the data for a user in a game. Returns a success message or an error message.

bool chatcommand_simplegameusersetdata::processmessage(char first_letter,message *received_message,chatclient *client)
{
	if ((first_letter != 's') 
		|| (received_message->actual_message.substr(0,22)!="simplegameusersetdata(")) {
		return false;
	}	
	
	Debug debug(__FILE__,__func__,__LINE__);
	message *new_message;
	datastring method_parameters;
	parameters parameters_parsed;
	bool parameter_success = true;
	int64_t messageid;
	datastring gameid;
	datastring username;
	datastring userdata;
	simplechatgame *game;
	biglist_item<simplechatgame *> *gamesearch;
	datastring error_message;	
	biglist_item<simplechatgameuser *> *usersearch;	
	simplechatgameuser *user;
	
	debug = __LINE__;
	method_parameters = received_message->actual_message.substr(22,received_message->actual_message.length-23);
	method_parameters.null_terminate(); // Used to comply with snprintf.
	parameters_parsed.long_parameter(method_parameters,parameter_success);
	parameters_parsed.string_parameter(method_parameters,parameter_success);
	parameters_parsed.string_parameter(method_parameters,parameter_success);
	parameters_parsed.string_parameter(method_parameters,parameter_success);
	
	debug = __LINE__;
	if (parameter_success) {
		// Give the parameters nice names.
		debug = __LINE__;
		messageid = parameters_parsed.long_parameters[0];
		gameid = parameters_parsed.string_parameters[1];
		username = parameters_parsed.string_parameters[2];
		userdata = parameters_parsed.string_parameters[3];
		
		printf("simplegameusersetdata(");
		gameid.print();
		printf(",");
		username.print();
		printf(",");
		userdata.print();	
		printf(")\n");
	
		debug = __LINE__;
		// Look to see if this gameid is already used.
		gamesearch = the_websocket->find_simple_game(gameid);
		if (gamesearch == nullptr) {
			error_message = "That gameid was not found.";
			error(client,error_message,messageid);
			return true;
		}
		game = gamesearch->item;
		debug = __LINE__;
		// Look for this client in this game.
		usersearch = game->getuser(client);
		debug = __LINE__;
		if (usersearch == nullptr) {
			error_message = "You're not in that game.";
			error(client,error_message,messageid);
			return true;
		}
		username = usersearch->item->username == nullptr ? datastring::anemptystring() : *(usersearch->item->username);
		debug = __LINE__;
		if ((userdata == nullptr) || (userdata.length == 0)) {
			debug = __LINE__;
			if (usersearch->item->userdata != nullptr) {
				idisposable::dereference((idisposable **)&(usersearch->item->userdata));
			}
			debug = __LINE__;
		} else {
			debug = __LINE__;
			if ((usersearch->item->userdata != nullptr) && (usersearch->item->userdata->capacity < userdata.length)) {
				idisposable::dereference((idisposable **)&(usersearch->item->userdata));
			}
			debug = __LINE__;
			if (usersearch->item->userdata == nullptr) {
				debug = __LINE__;
				datablock *userdata2 = new datablock(userdata);
				debug = __LINE__;
				usersearch->item->userdata = userdata2;
				debug = __LINE__;
				if (usersearch->item->userdata == nullptr) {
					error_message = "Out of memory.";
					error(client,error_message,messageid);
					return true;
				}
				debug = __LINE__;
			} else {
				debug = __LINE__;
				*(usersearch->item->userdata) == userdata;
			}
			debug = __LINE__;
		}
		debug = __LINE__;
		if (username.length > 0)
		{
			// Send a message to the other clients that the user data changed for this user.
			new_message = simplegameuserdata(messageid,gameid,username,userdata);
			debug = __LINE__;
			biglist_iterator<simplechatgameuser *> userloop(&(game->users));
			debug = __LINE__;
			while(!userloop.eof()) {
				debug = __LINE__;
				user = userloop.item;
				debug = __LINE__;
				if ((user->client != nullptr) && (user->client != client)) {
					user->client->add_message(new_message);
					user->client->callback_on_writable();
				}
				debug = __LINE__;
				userloop.movenext();
			}
			debug = __LINE__;
			idisposable::dereference((idisposable**)&new_message);
		}
		debug = __LINE__;
		// Send a success message to the client that changed the data.
		success_message(client,messageid);
	} else {
		debug = __LINE__;
		parameters_not_correct(client,received_message);
	}
	debug = __LINE__;
	return true;
}
